package com.maiji.cloud.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.maiji.cloud.config.MyRedisConfig;
import com.maiji.cloud.entities.login.AppUser;
import com.maiji.cloud.entities.login.AreaInfo;
import com.maiji.cloud.entities.shopingmall.RuleFreight;
import com.maiji.cloud.entities.shopingmall.ShopingAddress;
import com.maiji.cloud.entities.shopingmall.ShopingOrderEditLog;
import com.maiji.cloud.mapper.ShopingAddressMapper;
import com.maiji.cloud.microservice.UserInfoService;
import com.maiji.cloud.request.shopingmall.ShopingAddressAddReqDto;
import com.maiji.cloud.request.shopingmall.ShopingOrderEditLogReqData;
import com.maiji.cloud.response.*;
import com.maiji.cloud.response.shopingmall.DeliveryResData;
import com.maiji.cloud.response.shopingmall.ShopingAddressResData;
import com.maiji.cloud.response.shopingmall.ShopingOrderResData;
import com.maiji.cloud.service.RuleFreightService;
import com.maiji.cloud.service.ShopingAddressService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.maiji.cloud.microservice.AreaInfoService;
import com.maiji.cloud.service.ShopingOrderEditLogService;
import com.maiji.cloud.utils.Arith;
import com.maiji.cloud.utils.RedisUtil;
import com.maiji.cloud.utils.UUID_MD5;
import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class ShopingAddressServiceImpl extends ServiceImpl<ShopingAddressMapper, ShopingAddress> implements ShopingAddressService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private AreaInfoService areaInfoService;
    @Autowired
    private ShopingAddressMapper shopingAddressMapper;
    @Autowired
    private RuleFreightService ruleFreightService;
    @Autowired
    private ShopingOrderEditLogService shopingOrderEditLogService;

    @Override
    public ShopingAddressResData findShopingAddressResDataById (String shopingAddressId) {
        ShopingAddress shopingAddress = selectById(shopingAddressId);
        ShopingAddressResData shopingAddressResData = new ShopingAddressResData()
                .setAreaInfo(areaInfoService.getAreaInfoById(shopingAddress.getAreaInfoId()));
        BeanUtils.copyProperties(shopingAddress, shopingAddressResData);
        return shopingAddressResData;
    }

    @Override
    public BaseDataResDto<String> addOrUpdateShopingAddress(ShopingAddressAddReqDto.ShopingAddressAddReqReqData data, String token) {
        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, token, userInfoService);
        String userId = appUser.getUuId();
        String shopingAddressId = data.getShopingAddressId();
        String areaInfoId = data.getAreaInfoId();
        if (StringUtil.isNotBlank(shopingAddressId) && StringUtil.isNotBlank(areaInfoId)) {  // 修改收货地址
            AreaInfo areaInfo = areaInfoService.getAreaInfoById(areaInfoId);
            BeanUtil.copyProperties(data, areaInfo,true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            if (areaInfoService.updateAreaInfo(areaInfo.setUuId(areaInfoId))) {
                Integer isDefault = data.getIsDefault();
                if (isDefault != null && isDefault == 1) {
                    EntityWrapper<ShopingAddress> entityWrapper = new EntityWrapper<>();
                    entityWrapper.ne("uu_id", shopingAddressId);
                    entityWrapper.eq("is_default", 1);
                    ShopingAddress shopingAddressIsDefault = selectOne(entityWrapper);
                    if (shopingAddressIsDefault != null) updateById(shopingAddressIsDefault.setIsDefault(0));
                }
                ShopingAddress shopingAddress = selectById(shopingAddressId);
                BeanUtil.copyProperties(data, shopingAddress,true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
                if (shopingAddress.getIsDefault() == 1) update(new ShopingAddress().setIsDefault(0),
                        new EntityWrapper<ShopingAddress>().eq("user_id", userId).eq("auto", false));
                if (updateById(shopingAddress.setUuId(shopingAddressId))) return new BaseDataResDto<String>(Status.SUCCESS).setData(shopingAddressId);
            }
        }
        if (StringUtil.isBlank(shopingAddressId) && StringUtil.isBlank(areaInfoId)) {  // 添加收货地址
            AreaInfo areaInfo = new AreaInfo();
            BeanUtils.copyProperties(data, areaInfo);
            areaInfoId = UUID_MD5.getUUID();
            areaInfo.setUuId(areaInfoId);
            if (areaInfoService.saveAreaInfo(areaInfo)) {
                Integer isDefault = data.getIsDefault();
                if (isDefault != null && isDefault == 1) {
                    EntityWrapper<ShopingAddress> entityWrapper = new EntityWrapper<>();
                    entityWrapper.eq("is_default", 1);
                    ShopingAddress shopingAddressIsDefault = selectOne(entityWrapper);
                    if (shopingAddressIsDefault != null) updateById(shopingAddressIsDefault.setIsDefault(0));
                }
                ShopingAddress shopingAddress = new ShopingAddress();
                BeanUtils.copyProperties(data, shopingAddress);
                shopingAddress.setUuId(UUID_MD5.getUUID())
                        .setUserId(userId)
                        .setAuto(false)
                        .setAddDate(new Date())
                        .setAreaInfoId(areaInfoId);
                if (insert(shopingAddress)) return new BaseDataResDto<String>(Status.SUCCESS).setData(shopingAddress.getUuId());
            }
        }
        return new BaseDataResDto(Status.ERROR);
    }

    @Override
    public BaseResDto delShopingAddress(String shopingAddressId) {
        ShopingAddress shopingAddress = new ShopingAddress()
                .setUuId(shopingAddressId)
                .setIsDel(1);
        if (! updateById(shopingAddress))
            return new BaseResDto(Status.ERROR.setMessage("修改收货地址删除状态失败"));
        return new BaseResDto(Status.SUCCESS);
    }

    @Override
    public BaseMetaResDto<List<ShopingAddressResData>> findAllShopingAddress(String token) {
        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, token, userInfoService);
        String userId = appUser.getUuId();
        List<ShopingAddressResData> shopingAddressList = shopingAddressMapper.findAllShopingAddress(userId, null);
        if (shopingAddressList == null) return new BaseMetaResDto(Status.ERROR);
        return new BaseMetaResDto<List<ShopingAddressResData>>(Status.SUCCESS).setData(shopingAddressList);
    }

    @Override
    public void calculateFreight(ShopingOrderResData shopingOrderResData, String shopingAddressId,
                                 String rfId, String userId, Double presentPayable, Integer weight, Boolean submit) {
        RuleFreight ruleFreight = null;
                // 获取用户收货地址或默认收货地址省份快递计算规则
        EntityWrapper<ShopingAddress> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("user_id", userId).eq("auto", 0);
        if (StringUtil.isNotBlank(shopingAddressId)) entityWrapper.eq("uu_id", shopingAddressId);
        entityWrapper.orderDesc(Arrays.asList("is_default", "add_date"));
        List<ShopingAddress> shopingAddressList = selectList(entityWrapper);
        if (shopingAddressList.size() > 0) {
            ShopingAddress shopingAddress = shopingAddressList.get(0);
            AreaInfo areaInfo = areaInfoService.getAreaInfoById(shopingAddress.getAreaInfoId());
            shopingOrderResData.setScAmount(presentPayable).setWeightTotal(weight);
            ruleFreight = ruleFreightService.findAllRuleFreightsByOrder(shopingOrderResData, areaInfo, rfId);
            if (submit) { // 提交订单时固定收货地址
                areaInfoService.saveAreaInfo(areaInfo.setUuId(UUID_MD5.getUUID()));
                insert(shopingAddress.setUuId(UUID_MD5.getUUID()).setAreaInfoId(areaInfo.getUuId()).setAuto(true));
            }
            ShopingAddressResData shopingAddressResData = new ShopingAddressResData();
            BeanUtils.copyProperties(shopingAddress, shopingAddressResData);
            shopingOrderResData.setShopingAddressId(shopingAddress.getUuId());
            shopingOrderResData.setShopingAddress(shopingAddressResData.setAreaInfo(areaInfo));
        }
        System.out.println("AAAAAAAAAAAAAAAAAAAAAAAA" + Thread.currentThread().getName() + ruleFreight);
        if (ruleFreight == null) {  // 获取“全国”快递计算规则
            String redisKey = RedisUtil.getRedisKey(ruleFreightService.REDISNAMESPACE, "全国");
            ruleFreight = (RuleFreight) redisTemplate.opsForValue().get(redisKey);
            if (ruleFreight == null) {
                ruleFreight = ruleFreightService.selectOne(new EntityWrapper<RuleFreight>().like("area_names", "全国"));
                if (ruleFreight != null) {
                    RedisUtil.setObject(redisTemplate, redisKey, ruleFreight);
                    List<DeliveryResData> deliveryList = Arrays.asList(new DeliveryResData().setUuId(ruleFreight.getUuId())
                            .setDelivery(ruleFreight.getDelivery()).setDeliveryFee(ruleFreight.getFreight()));
                    shopingOrderResData.setDeliveryList(deliveryList);
                }
            }
        }
        //  计算快递费
        Double freight = 0.00;
        Double freeFreight = ruleFreight.getFreeFreight();
        Integer headWeight = ruleFreight.getHeadWeight();
        if (presentPayable < freeFreight)   // 购物金额 < 包邮购物金额
            if (weight > headWeight) {  // 物流总重量 > 物流首重量
                Integer moreWeight = weight - headWeight;
                Integer more = moreWeight / 1000 + 1;
                freight = Arith.add(2, ruleFreight.getFreight(), Arith.multiplys(2, ruleFreight.getMoreFreight(), more));
            } else freight = ruleFreight.getFreight();  // 物流总重量 <= 物流首重量
        shopingOrderResData.setDelivery(ruleFreight.getDelivery())
                .setDeliveryFee(freight)
                .setAmount(Arith.add(2, presentPayable, freight));
    }

    @Override
    public BaseResDto editOrder(ShopingOrderEditLogReqData data) {
        if (StringUtil.isNotBlank(data.getShopingAddressId())) {
            ShopingAddress shopingAddress = new ShopingAddress().setUuId(data.getShopingAddressId());
            if (StringUtil.isNotBlank(data.getConsigneeNew())) shopingAddress.setConsignee(data.getConsigneeNew());
            if (StringUtil.isNotBlank(data.getTelNew())) shopingAddress.setTel(data.getTelNew());
            if (! updateById(shopingAddress)) return new BaseResDto(Status.ERROR);
        }
        if (StringUtil.isNotBlank(data.getAreaInfoId())) {
            AreaInfo areaInfo = new AreaInfo()
                    .setUuId(data.getAreaInfoId())
                    .setProvince(data.getProvince())
                    .setCity(data.getCity())
                    .setCounty(data.getCounty())
                    .setAddress(data.getAddress());
            if (! areaInfoService.updateAreaInfo(areaInfo)) return new BaseResDto(Status.ERROR);
        }
        if (! shopingOrderEditLogService.save(data)) return new BaseResDto(Status.ERROR);
        return new BaseResDto(Status.SUCCESS);
    }

}
